package reflect;

import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * JAVA反射机制
 * 反射是java的动态机制，它允许将对象的实例化，方法的调用，属性的操作等从编码期确定转移
 * 到程序运行期确定。这大大的提高了代码的灵活度。
 * 反射带来了更多的系统开销和较慢的运行效率，因此程序不能过度依赖反射。
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {//Class Not Found Exception:找不到类异常
         /*
            反射的第一步就是要获取操作类的类对象，一个Class的实例。
            JVM中每个被加载的类有且只有一个类对象与之对应，获取到这个类对象后我们就可以
            通过这个类对象来了解该类的一切信息(类名，有哪些方法，属性等等)以便在程序运行
            期间通过反射机制进行相关操作。

            获取一个类的类对象有以下几种方式:
            1:类名.class
            例如:  Class cls = String.class;
                  Class cls = int.class;
            这种方式最直接，但是由于是靠硬编码形式写死，因此不够灵活。但是需要注意，
            (基本类型只能通过这种方式获取类对象)

            2:Class.forName(String className)
            例如:
            Class cls = Class.forName("java.lang.String");

            3:类加载器ClassLoader
         */
        /** 1.类名.class:获取一个类的类对象() */
        Class cla = String.class;
        String name1 = cla.getName();//获取类的完全限定名:包名.类名
        System.out.println("类名:"+name1);
        name1 = cla.getSimpleName();//仅仅获取类名
        System.out.println("类名:"+name1);
        /*
            Method[] getMethods()
            获取Class所表示的类的所有公开方法(包含从超类继承的方法)
         */
        Method[] method = cla.getMethods();
        for(Method m : method){
            System.out.println(m.getName());//遍历获取所有方法名.
        }

        /** 2:Class.forName(String className) */
//        Class cls = Class.forName("java.lang.String");
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入类名:");
        String className = scan.nextLine();
        Class cls = Class.forName(className);
        /*
            java.long.String
            java.util.ArrayList
            java.util.HashSet
            java.util.HashMap
            java.io.FileOutputStream
            java.net.Socket
         */
        String name = cls.getName();
        System.out.println("类名:" + name);
        name = cls.getSimpleName();
        System.out.println("类名:" + name);

        Method[] methods = cls.getMethods();
        for (Method m : methods) {
            System.out.println(m.getName());
        }
        /*
        请输入类名:
        reflect.Person
        类名:reflect.Person
        类名:Person
        sayHello
        sayGoodBye
        say
        say
        wait
        wait
        wait
        .......
         */






    }
}
